/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managers;

import entities.Article;
import entities.ArticleState;
import entities.Bid;
import entities.Category;
import entities.UserProject;
import interfaces.ArticleInterface;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Thibault
 */
@Stateless
public class ArticleManager implements ArticleInterface {

    @PersistenceContext(unitName = "project")
    private EntityManager em;

    @Override
    public void createArticle(Article article) {
        em.persist(article);
    }

    @Override
    public Article findById(long id) throws EJBException {
        Article a = em.find(Article.class, id);
        if (a != null) {
            return a;
        } else {
            throw (new EJBException("No Article entity found for id " + id));
        }
    }

    @Override
    public void removeArticle(long id) throws EJBException {
        em.remove(em.find(UserProject.class, id));
    }

    @Override
    public void updateArticle(Article article) {
        em.merge(article);
    }

    @Override
    public List<Article> getListArticleForUserId(Long id) {
        Query query =
                em.createNamedQuery("Article.getListArticleForUserId");
        query.setParameter("id", id);
        try {
            return (List<Article>) query.getResultList();
        } catch (NoResultException nre) {
            return new ArrayList<Article>();
        }
    }

    @Override
    public List<Article> getListArticleForUserIdAndState(Long id, ArticleState articleState) {

        Query query =
                em.createNamedQuery("Article.getListArticleForUserIdAndState");
        query.setParameter("id", id);
        query.setParameter("articleState", ArticleState.valueOf(articleState.name()));
        return (List<Article>) query.getResultList();

    }

    @Override
    public void cancelArticle(Article selectedArticle) throws IllegalArgumentException {
        if (selectedArticle.getArticleState() != ArticleState.forSale) {
            throw new IllegalArgumentException("The article must be in forSale status to be canceled.");
        }
        selectedArticle.setArticleState(ArticleState.canceled);
        //Cancel all bids
        selectedArticle.getBiddingHistory().clear();
        this.updateArticle(selectedArticle);
    }

    @Override
    public void reSaleArticle(Article selectedArticle, Date newEndAuction) throws IllegalArgumentException {
        if (selectedArticle.getArticleState() != ArticleState.canceled) {
            throw new IllegalArgumentException("The article must be in forSale status to be canceled.");
        }
        selectedArticle.setArticleState(ArticleState.forSale);
        selectedArticle.setEndSale(newEndAuction);
        this.updateArticle(selectedArticle);
    }

    @Override
    public void acceptAuction(Article selectedArticle) {
        if (selectedArticle.getArticleState() != ArticleState.forSale) {
            throw new IllegalArgumentException("The article must be in forSale status to be sold.");
        }
        selectedArticle.setArticleState(ArticleState.sold);
        
        //Only persist the winning bid
        for (Bid bid : selectedArticle.getBiddingHistory()) {
            if (!bid.equals(selectedArticle.getWinningBid())) {
                selectedArticle.getBiddingHistory().remove(bid);
            }
        }
        this.updateArticle(selectedArticle);
    }

    @Override
    public List<Article> searchByName(String keyWord) {
        Query query =
                em.createNamedQuery("Article.searchByName");
        query.setParameter("keyWord", "%" + keyWord.toUpperCase() + "%");
        return (List<Article>) query.getResultList();
    }

    @Override
    public List<Article> searchByNameAndCategories(String keyWord, List<Category> categories) {
        List<Article> result = new ArrayList<Article>();
        Query query = em.createNamedQuery("Article.searchByNameAndCategory");
        query.setParameter("keyWord", "%" + keyWord.toUpperCase() + "%");
        for (Category c : categories) {
            query.setParameter("category", c.name());
            result.addAll((List<Article>) query.getResultList());
        }
        return result;
    }
}
